package Collision;

import Bubble.BubblePath;
import Bubble.BubbleShot;
import Bubble.Bubble;
import Bubble.Bubbles;

import com.golden.gamedev.object.Sprite;
import com.golden.gamedev.object.collision.BasicCollisionGroup;

/**
 * A collision manager handling the event that a bubble shoots another bubble
 * Group one is BubblePath
 * Group two is BubbleShot
 * @author Yin
 *
 */
public class ShotCollision extends BasicCollisionGroup 
{	
	private final int RAD_BUBBLE = 13;
	private int myCombo;
	private int myLevelScore;
	private int myTotalScore;
	private int myTotalSavedFish;
	private int myFishToSave;
	private double myTime;
	
	public ShotCollision()
	{
		myCombo = 0;
		myLevelScore = 0;
		myTotalScore = 0;
		myTotalSavedFish = 0;
		myFishToSave = 0;
		myTime = 0;
	}
	
	public void setFish(int saved, int toSave)
	{
		myTotalSavedFish = saved;
		myFishToSave = toSave;
	}
	
	public void setScore(int level, int total)
	{
		myLevelScore = level;
		myTotalScore = total;
	}
	
	public void setTime(double time)
	{
		myTime = time;
	}
	
	@Override
	public void collided(Sprite bubPath, Sprite bubShot) 
	{
		BubblePath bubblePath = (BubblePath)getGroup1();
		Bubble bub = (Bubble) bubPath;
		
		double f10 = (!bubblePath.isFirst(bub)) ? 
				Math.min(bubblePath.getList().get(0).getX(), bubPath.getX()) : bubPath.getX() - RAD_BUBBLE;
        double f11 = (!bubblePath.isFirst(bub)) ? 
        		Math.max(bubblePath.getList().get(0).getX(), bubPath.getX()) : bubPath.getX();
        double f12 = (!bubblePath.isFirst(bub)) ? 
        		bubblePath.getList().get(0).getX() - bubPath.getX() : (bubPath != bubblePath.getList().getLast()) ? 
        				bubPath.getX() - bubblePath.getList().get(bubblePath.getList().indexOf(bubPath)+1).getX() : 1;
        double f15 = (!bubblePath.isFirst(bub)) ? 
        		bubblePath.getList().get(0).getY() - bubPath.getY() : (bubPath != bubblePath.getList().getLast()) ? 
        				bubPath.getY() - bubblePath.getList().get(bubblePath.getList().indexOf(bubPath)+1).getY() : 0;
        double f16 = Math.sqrt(f12 * f12 + f15 * f15);
        f15 /= f16;
        boolean flag2 = true;
        
        if (Math.abs(f15) > 0.4)
        {
            flag2 = (f15 < 0);
        }
        else
        {
            flag2 = ! ((!bubblePath.isFirst(bub) && bubShot.getX() > f10 || bubblePath.isFirst(bub)) && bubShot.getX() < f11);
        }
        
        // insert bubShot after bubPath
        if (!flag2)
        {
            bubblePath.add(bubblePath.getList().indexOf(bubPath), bubShot);
        }
        else // insert bubShot before bubPath
        {
            bubblePath.add(bubblePath.getList().indexOf(bubPath)+1, bubShot);
        }
		
		// TODO: should check whether the new bubble can burst
		// If burst, score increases
        
        // Determine whether it is ok to burst
        if (!bubblePath.isLast(bub))
        {
        	int i = 1;
            boolean flag =bub.getShot();
            if (bubblePath.isFirst(bub) || bubblePath.getBubble(bubblePath.getList().indexOf(bub)-1) != bub)
            {
                int idx = bubblePath.getList().indexOf(bub);
            	Bubble bubble3 = bubblePath.getBubble(idx++);
            	while(bubble3!=null)
                {
                	if (bubble3.getT() - (i+bub.getT())>0.01)
                	{
                		i = 0; break;
                	}
                	if (bubble3.getShot())
                	{
                		flag = true;
                	}
                	i++;
                }
            	
            	if (flag && i >= 3)
            	{
            		// Burst
            		// TODO: play sound
            		myLevelScore += i * 50;
            		myTotalScore += i * 50;
            		
            		// TODO: check whether bonus is acting
            		
            		boolean flag1 = false;
                    int j = 1;
                    double curr_x = 0;
                    double curr_y = 0;
                    
                    for (int k = i; k > 0; k--)
                    {
                    	curr_x += bub.getX();
                        curr_y += bub.getY();
                        j += bub.getCombo();
                        
                        if (bub.isFishInside())
                        {
                            myTotalSavedFish++;
                            myFishToSave--;
                            // TODO: add Partss
                        }
                        
                        // TODO: spawn burst
                        
                        // delete bubPath
                        if (bubblePath.isLast(bub))
                        	flag1 = true;
                        bubblePath.remove(bub);
                        
                        curr_x /= i;
                        curr_y /= i;
                        idx = bubblePath.getList().indexOf(bub);
                        if (bub != null && bubblePath.adjIsGoingToBurst(idx, bub))
                        {
                            bub.setCombo(j);
                        }
                        
                        if (j > 1)
                        {
                            //TODO: add Parts
                        }
                        
                        // TODO: update longest_combo
                        // TODO: play combo sound
                        
                        if (bub!= null && !bubblePath.isFirst(bub) && !flag1)
                        {
                            if (bub.getImage() == bubblePath.getList().get(bubblePath.getList().indexOf(bub)-1).getImage())
                            	bub.setShot(true);
                        }
                        
                    } // for k
                    
                    if (bubblePath.getList().size()==0)
                    {
                        if (myFishToSave <= 0)
                        {
                            // TODO: mark level as completed
                        	//level_completed = true;
                        }
                        //if (level_completed)
                        if (myFishToSave <= 0) // TODO: should set if (level_complete)
                        {
                            // TODO: clear group 2
                            return;
                        }
                        else
                        {
                        	// Remove bubbleShot from myBubbleShot
                            ((BubbleShot)getGroup2()).shoot();	
                            return;
                        }
                    }
                    
                    if (bubblePath.isLast(bub))
                    {
                        return;
                    }
                    
                    double f14 = Math.abs(bubblePath.getBubble(idx+1).getT() - bub.getT());
                    if (f14 < 0.99)
                    {
                        int idxtmp = idx + 1;
                    	for (Bubble bubble4 = bubblePath.getBubble(idxtmp++); bubble4 != null; idxtmp++, bubble4 = bubblePath.getBubble(idxtmp))
                        {
                            double f18 = 6 * (1 - f14) * myTime;
                            if (f18 > f14)
                                f18 = f14;
                            bubble4.setT(bubble4.getT()+f18);
                        }
                    }
                    
                    if (f14 > 1.01)
                    {
                    	int idxtmp = idx + 1;
                    	for(Bubble bubble5 = bubblePath.getBubble(idxtmp++); bubble5 != null; idxtmp++, bubble5 = bubblePath.getBubble(idxtmp))
                        {
                            double f19 = 2 * f14 * myTime;
                            if (f19 > 0.15)
                            {
                                f19 = 0.15;
                            }
                            if (f19 > f14)
                            {
                                f19 = f14;
                            }
                            bubble5.setT(bubble5.getT()-f19);
                        }
                    }
            	} // if (flag && i >= 3)
            	
            	if (bub.getCombo() > 0 && !bubblePath.adjIsGoingToBurst(idx, (Bubble) bubShot))
                {
                    bub.setCombo(0);
                }
            }
        }
	}
	
}
